﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using UnityEngine;

public class SystemReturn
{
	private static SystemReturn self;
	private ModelLocator model;

	public SystemReturn ()
	{
//        if (self == null)
//        {
//            throw new Exception("init error");
//        }
		model = ModelLocator.getInstance ();
		addEvents ();
	}

	public static void StartListen ()
	{
		if (self == null)
			self = new SystemReturn ();
	}

	private void addEvents ()
	{
		MySocket.getInstance ().addEventListener (CustomToClientFlag.SERVER_CUSTOMMSG_ADD_OBJECT, SceneAddObject);//增加对象（主角）
		MySocket.getInstance ().addEventListener (SystemMsgFlag.SERVER_CUSTOM, ServerCustom);//自定义消息消息头20

		MySocket.getInstance ().addEventListener ((int)SystemMsgFlag.MessageTypeSC.NSM_SYNC_PSH, SyncMessage);//同步消息

		//表格相关增/删/改/
		MySocket.getInstance ().addEventListener (SystemMsgFlag.SERVER_RECORD_ADDROW, ServerRecordAddRow);
		MySocket.getInstance ().addEventListener (SystemMsgFlag.SERVER_RECORD_DELROW, ServerRecordDelRow);
		MySocket.getInstance ().addEventListener (SystemMsgFlag.SERVER_RECORD_GRID, ServerRecordGrid);
		
		ModelLocator.getInstance ().addEventListener (CustomToClientFlag.SERVER_CUSTOMMSG_ADD_MAINROLE, SceneAddMainRole);//增加对象（主角）
	}
	
	private void SceneAddMainRole (System.Object obj, DispatchEventArgs e)
	{
		ByteArrayEx btArr = (ByteArrayEx)e.data [0];
		
		btArr.readByte ();
		Point objID = btArr.readObject ();
        int sceneID = btArr.readInt ();
        PlayerData.Instance().SceneId = sceneID;
        PlayerData.Instance().SceneType = int.Parse(SqliteReader.getInstance().getIniVal("SceneInfo", "SceneID", sceneID.ToString(), new string[] { "Maptype" })[0]);

		string playerName = btArr.readMultiByteEx ();
		byte profession = btArr.readByte ();
		byte sex = btArr.readByte ();
		
		string modelPath = modelPath = SqliteReader.getInstance ().getIniVal ("RoleInfo", "RoleID", profession.ToString (), new string[]{"ModelName"}) [0];
		
		string headPic = btArr.readMultiByteEx ();
		model.scene.Role.ObjID = objID;
		Debug.Log("Role #####  " + objID.ToString());
		model.scene.HandlePropertiesEx (objID.ToString (), model.scene.Role);

		model.scene.AddMainRole (objID, playerName, modelPath, headPic, (int)profession);
	}
	
	/// <summary>
	/// 增加主角对象
	/// </summary>
	private void SceneAddObject (System.Object obj, DispatchEventArgs e)
	{
		ByteArrayEx btArr = new ByteArrayEx ((byte[])e.data [0]);
		Point objID = btArr.readObject ();
		int objType = btArr.readInt ();
		int objModelID = btArr.readInt ();
		int count = btArr.readInt ();
		model.scene.Role.ObjID = objID;

		model.scene.AddObj (objID, objType, objModelID, count, btArr);

	}
	/// <summary>
	/// 同步消息
	/// </summary>
	private void SyncMessage (System.Object obj, DispatchEventArgs e)
	{
		ByteArrayEx msg = new ByteArrayEx ((byte[])e.data [0]);

		int syncType = (int)msg.readByte ();//同步消息类型(0:场景;1:对象)//

		
		if (syncType == 1) {
			int objMessageType = (int)msg.readByte ();//对象消息类型：0 新增 1 删除 2 改变 //

			if (objMessageType == 0) {
				//基本信息//
				Point ObjID = msg.readObject ();//对象ID//
				int objType = (int)ObjID.QueryType ();
				int sceneID = (int)msg.readInt ();//所在场景ID//
				UInt64 parentID = (UInt64)msg.readUInt64 ();//父对象ID//
				int PosX = (int)msg.readInt ();//位置x//
				int PosY = (int)msg.readInt ();//位置y//
				int tag = (int)msg.readInt ();//Tag//

				switch (objType) {
				case ObjType.Npc:
				case ObjType.Monster:
					int MonsterObjState = (int)msg.readByte ();//对象状态//
					int MonsterMoveState = (int)msg.readByte ();//移动状态//
					break;
				case ObjType.Player:
					int PlayerObjState = (int)msg.readByte ();//对象状态//
					int PlayerMoveState = (int)msg.readByte ();//移动状态//
					int PlayerIsVisible = (int)msg.readInt ();//玩家可见性//
					break;
				}
				
				SceneObject sceneAddObj;
				if(model.scene.CheckProperties(ObjID.ToString()))
				{
					sceneAddObj = (SceneObject)model.scene.GetProperties(ObjID.ToString());
				}
				else
				{
					sceneAddObj = new SceneObject (ObjID, 0, 0);
					model.scene.HandlePropertiesEx (ObjID.ToString (), sceneAddObj);
				}
				sceneAddObj.HandlePropertiesEx ("PosX", PosX);
				sceneAddObj.HandlePropertiesEx ("PosY", PosY);

				while (msg.bytesAvailable > 0) {
					int addType = (int)msg.readByte ();//字段类型：0 属性字段1 表字段//
					if (addType == 0) {
						int addFieldNum = (int)msg.readUnsignedShort ();//字段数量[uint16]//
						for (int h = 0; h < addFieldNum; h++) {
							string addFieldName = msg.readMultiByteEx ();//字段名//
							int subAddFieldType = (int)msg.readByte ();//字段类型//
							System.Object addKeyValue = msg.GetDataByType (subAddFieldType);
							sceneAddObj.HandlePropertiesEx (addFieldName, addKeyValue);
						}
					} else if (addType == 1) {
						int addRecordNum = (int)msg.readUnsignedShort ();//表数量//
						for (int l = 0; l < addRecordNum; l++) {
							string recordName = msg.readMultiByteEx ();//表名//
							Record objRecord;
							if (!sceneAddObj.CheckProperties (recordName)) {
								objRecord = new Record (recordName);
							} else {
								objRecord = sceneAddObj.GetProperties (recordName) as Record;
							}
                            Debug.Log("recordName " + recordName);

							int rowNums = (int)msg.readInt ();//行数//
							int colNums = (int)msg.readUnsignedShort ();//列数//

							for (int mm = 0; mm < colNums; mm++) {
								string fieldName = msg.readMultiByteEx ();//字段名//
								int fieldType = msg.readByte ();//字段类型//
							}

							for (int z = 0; z < rowNums; z++) {
								int rowNum = (int)msg.readInt () - 1;//行号//
								objRecord.AddRecordRow (rowNum, colNums, msg);
							}
							sceneAddObj.HandlePropertiesEx (recordName, objRecord);
						}
					}
				}
                
			} else if (objMessageType == 2) {
				//基本信息//
				Point ObjID = msg.readObject ();//对象ID//
				int objType = (int)ObjID.QueryType ();
				int sceneID = (int)msg.readInt ();//所在场景ID//
				UInt64 parentID = (UInt64)msg.readUInt64 ();//父对象ID//
				int PosX = (int)msg.readInt ();//位置x//
				int PosY = (int)msg.readInt ();//位置y//
				int tag = (int)msg.readInt ();//Tag//

				switch (objType) {
				case ObjType.Npc:
				case ObjType.Monster:
					int MonsterObjState = (int)msg.readByte ();//对象状态//
					int MonsterMoveState = (int)msg.readByte ();//移动状态//
					break;
				case ObjType.Player:
					int PlayerObjState = (int)msg.readByte ();//对象状态//
					int PlayerMoveState = (int)msg.readByte ();//移动状态//
					int PlayerIsVisible = (int)msg.readInt ();//玩家可见性//
					break;
				}
				
				SceneObject sceneObj = model.scene.isRole (ObjID) ? model.scene.Role : (SceneObject)model.scene.GetProperties (ObjID.ToString ());
				sceneObj.HandlePropertiesEx ("PosX", PosX);
				sceneObj.HandlePropertiesEx ("PosY", PosY);

				while (msg.bytesAvailable > 0) {

					int operateType = (int)msg.readByte ();//操作类型:0 新增字段 1 删除字段 2 改变字段//

					if (operateType == 0) {
						int addType = (int)msg.readByte ();//字段类型：0 属性字段1 表字段//
						if (addType == 0) {
							int addFieldNum = (int)msg.readUnsignedShort ();//字段数量[uint16]//
							for (int h = 0; h < addFieldNum; h++) {
								string addFieldName = msg.readMultiByteEx ();//字段名//
								int subAddFieldType = (int)msg.readByte ();//字段类型//
								System.Object addKeyValue = msg.GetDataByType (subAddFieldType);
								sceneObj.HandlePropertiesEx (addFieldName, addKeyValue);
							}
						} else if (addType == 1) {
							int addRecordNum = (int)msg.readUnsignedShort ();//表数量//
							for (int l = 0; l < addRecordNum; l++) {
								string recordName = msg.readMultiByteEx ();//表名//

								Record objRecord;

								if (!sceneObj.CheckProperties (recordName)) {
									objRecord = new Record (recordName);
								} else {
									objRecord = sceneObj.GetProperties (recordName) as Record;
								}

								int rowNums = (int)msg.readInt ();//行数//
								int colNums = (int)msg.readUnsignedShort ();//列数//

								for (int mm = 0; mm < colNums; mm++) {
									string fieldName = msg.readMultiByteEx ();//字段名//
									int fieldType = msg.readByte ();//字段类型//
								}

								for (int z = 0; z < rowNums; z++) {
									int rowNum = (int)msg.readInt () - 1;//行号//
									objRecord.AddRecordRow (rowNum, colNums, msg);
								}
								sceneObj.HandlePropertiesEx (recordName, objRecord);
							}
						}
					} else if (operateType == 2) {
						int fieldType = (int)msg.readByte ();//字段类型：0 属性字段 1 表字段//
						if (fieldType == 0) {
							int fieldNum = (int)msg.readUnsignedShort ();//字段数量[uint16]//
							for (int j = 0; j < fieldNum; j++) {
								string fieldName = msg.readMultiByteEx ();//字段名//
								int subFieldType = (int)msg.readByte ();//字段类型//
								System.Object keyValue = msg.GetDataByType (subFieldType);
								sceneObj.HandlePropertiesEx (fieldName, keyValue);
							}
						} else if (fieldType == 1) {
							int recordNum = (int)msg.readUnsignedShort ();//表数量//
							for (int k = 0; k < recordNum; k++) {
								string recordName = msg.readMultiByteEx ();//表名//
								Record objRecord = (Record)sceneObj.GetProperties (recordName);

								int rowNums = (int)msg.readInt ();//行数//
								int colNums = (int)msg.readUnsignedShort ();//列数//
								for (int m = 0; m < rowNums; m++) {
									int rowNum = (int)msg.readInt () - 1;//行号//
									int actType = (int)msg.readByte ();//行为[0:增，1:删，2:改]//
									if (actType == 0) {
										objRecord.AddRecordRow (rowNum, colNums, msg);
									} else if (actType == 2) {
										objRecord.ChangeRecord (rowNum, colNums, msg);
									} else if (actType == 1) {
										objRecord.DelRow (rowNum);
									}
								}
							}
						}


					} else if (operateType == 1) {
						int num = msg.readUnsignedShort ();//数量[uint16]//
						for (int i = 0; i < num; i++) {
							string keyName = msg.readMultiByteEx ();//字段名//
							int type = msg.readByte ();//字段类型: 0为字段  1为表数据//
							sceneObj.DeletePropertiesEx (keyName);
						}
					}

				}

			} else if (objMessageType == 1) {
				Point objID = msg.readObject ();//对象ID//
				model.scene.DelObjByCustom (objID);
			}
		} else if (syncType == 0) {

		}





	}

	/// <summary>
	/// 自定义消息，增/删/改/场景对象
	/// </summary>
	private void ServerCustom (System.Object obj, DispatchEventArgs e)
	{
		ByteArrayEx msg = new ByteArrayEx ((byte[])e.data [0]);
		if (msg.length <= 20) {
			//消息不完整，自定义消息没有任何数据，因为自定义消息的最短长度应该大于20//
			Console.WriteLine ("错误", "自定义消息没有数据");
			return;
		}

		//Point ObjectId		= msg.readObject();
		//Point AsyncId		= msg.readObject();
		int nArgNum = msg.readInt ();    //参数数量

		int type = msg.readByte ();


		int command = (int)msg.GetDataByType (type);

		object[] ArgValue = new object[nArgNum];

		for (int i = 0; i < nArgNum - 1; i++) {
			type = msg.readByte ();
			ArgValue [i] = msg.GetDataByType (type);
		}

		switch (command) {
		case CustomToClientFlag.SERVER_CUSTOMMSG_ADD_OBJECT://添加对象//
			model.scene.AddObjByCustom (ArgValue);
			break;
		case CustomToClientFlag.SERVER_CUSTOMMSG_OBJECT_PROPERTY_CHANGE://显示对象属性修改//
			model.scene.UpdataObjByCustom (ArgValue);
			break;
		case CustomToClientFlag.SERVER_CUSTOMMSG_OBJECT_DEL://删除显示对象//
                //model.scene.DelObjByCustom(ArgValue);
			break;
		default:
			break;
		}
		model.dispacthEvent (command, ArgValue);
	}

	/// <summary>
	/// 表格增加行
	/// string	表名
	/// int 插入行号
	/// int 插入行数
	/// </summary>
	private void ServerRecordAddRow (System.Object obj, DispatchEventArgs e)
	{
		ByteArrayEx msg = new ByteArrayEx ((byte[])e.data [0]);

		string recName = msg.readMultiByteEx ();
		int nRow = msg.readInt ();
		int nRows = msg.readInt ();

		Debug.Log ("↓收到引擎消息(表格添加行)+" + "recordName" + recName + ",nRow:" + nRow + ",nRows:" + nRows);

		if (!model.scene.CheckProperties (recName)) {
			//表格不存在
			Debug.Log ("不存在名为[" + recName + "]表格！表格数据添加失败。");
			return;
		}
		Record record = model.scene.GetProperties (recName) as Record;

		record.AddRow (nRow, nRows, msg);
	}
	/// <summary>
	/// 删除表格行
	/// string 表名
	/// int 删除行号
	/// </summary>
	private void ServerRecordDelRow (System.Object obj, DispatchEventArgs e)
	{
		//			_UI16	nIndex;		// 表序号
		//			_UI16	nRow;		// 删除的行号

		ByteArrayEx msg = new ByteArrayEx ((byte[])e.data [0]);
		string recName = msg.readMultiByteEx ();
		int nRow = msg.readInt ();


		Debug.Log ("↓收到引擎消息(表格删除行),recName:" + recName + ",nRow:" + nRow);

		if (!model.scene.CheckProperties (recName)) {
			//表格不存在
			Debug.Log ("不存在名为[" + recName + "]表格！表格数据删除失败。");
			return;
		}
		Record record = model.scene.GetProperties (recName) as Record;
		record.DelRow (nRow);
	}
	/// <summary>
	/// 表数据修改
	/// string 表名
	/// int 要修改的数据数量
	/// msg 包含，行，列，及数据
	/// </summary>
	private void ServerRecordGrid (System.Object obj, DispatchEventArgs e)
	{
		ByteArrayEx msg = new ByteArrayEx ((byte[])e.data [0]);
		string recName = msg.readMultiByteEx ();
		int nCount = msg.readInt ();


		Debug.Log ("↓收到引擎消息(表格修改行),recName:" + recName + ",nCount:" + nCount);

		if (!model.scene.CheckProperties (recName)) {
			//表格不存在
			Debug.Log ("不存在名为[" + recName + "]表格！表格数据修改失败。");
			return;
		}
		Record record = model.scene.GetProperties (recName) as Record;
		record.ChangeRecordGrid (nCount, msg);
	}


}